package com.business.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.business.action.admin.database.ClassBeanAction.ClassTree;

import net.sf.rose.jdbc.ConstantCode;
import net.sf.rose.jdbc.bean.FieldBean;
import net.sf.rose.jdbc.bean.TableBean;
import net.sf.rose.util.DateFormat;
import net.sf.rose.util.StringUtil;

public class JavaBeanBuilder {

	/** 文件存储路径 */
	private File path = null;

	/** 类名 */
	private String className = null;

	/** 文件代码 */
	private String code = null;

	public File getPath() {
		return path;
	}

	public String getCode() {
		return code;
	}

	public void build(File path, ClassTree tree) {
		// 根据包名生成包路径
		this.path = path;
		List<TableBean> tables = tree.getTableList();
		TableBean bean = tables.get(0);
		String pn = bean.getClassName();
		int index = pn.lastIndexOf('.');
		this.className = pn.substring(index + 1, pn.length());
		pn = pn.substring(0, index);
		if (pn != null) {
			String[] arr = StringUtils.split(pn, '.');
			for (String s : arr) {
				this.path = new File(this.path, s);
				if (!this.path.exists()) {
					this.path.mkdirs();
				}
			}
		}
		String now = DateFormat.format(new Date(), DateFormat.DATE_FORMAT_1);
		StringBuilder sb = new StringBuilder();
		// 头部说明
		sb.append("package ").append(pn).append(";\n\n");
		sb.append("import net.sf.rose.jdbc.bean.annotation.Column;\n");
		sb.append("import net.sf.rose.jdbc.bean.annotation.Table;\n");
		if (tables.size() > 1) {
			sb.append("import net.sf.rose.jdbc.bean.annotation.View;\n");
		}
		sb.append("import net.sf.rose.jdbc.bean.annotation.Type;\n");
		sb.append("\n");
		sb.append("/**\n");
		sb.append(" * @author system E-mail: 9110530@qq.com\n");
		sb.append(" * @version 创建时间：").append(now).append('\n');
		sb.append(" * 类说明：").append('\n');
		sb.append(" */\n");

		// 类说明
		sb.append("@Table(database = \"").append(bean.getDatabaseName()).append('\"');
		sb.append(", name = \"").append(bean.getTableName()).append('\"');
		sb.append(", description = \"").append(bean.getDescription()).append('\"');
		sb.append(")\n");
		if (tables.size() > 1) {
			for (int i = 1; i < tables.size(); i++) {
				TableBean t = tables.get(i);
				sb.append("@View(database = \"").append(bean.getDatabaseName()).append('\"');
				sb.append(", name = \"").append(bean.getTableName()).append('\"');
				sb.append(", description = \"").append(t.getDescription()).append('\"');
				sb.append(")\n");
			}
		}
		sb.append("public class ").append(className).append(" {\n");

		// 属性定义
		for (FieldBean f : tree.getFields()) {
			sb.append('\n');
			sb.append("\t@Column(type = Type.").append(f.getType());
			sb.append(", description = \"").append(f.getDescription()).append('\"');
			if (!f.isCanNull()) {
				sb.append(", canNull = false");
			}
			if (f.getSize() != 0) {
				sb.append(", size = ").append(f.getSize());
			}
			if (f.getScale() != 0) {
				sb.append(", scale = ").append(f.getScale());
			}
			if (f.getPolicy() != null) {
				sb.append(", policy = \"").append(f.getPolicy()).append('\"');
			}
			sb.append(")\n");
			sb.append("\tprivate ").append(getShortJavaType(f)).append(' ').append(f.getFieldName());
			if (f.getDefaultValue() != null) {
				sb.append(" = ");
				if (FieldBean.isStringType(f)) {
					sb.append('\"').append(f.getDefaultValue()).append('\"');
				} else {
					sb.append(f.getDefaultValue());
				}
			}
			sb.append(";\n");
		}
		// Get和Set方法
		for (FieldBean f : bean.getFields()) {
			String type = getShortJavaType(f);
			sb.append('\n');
			String upName = StringUtil.firstLetterUpper(f.getFieldName());
			sb.append("\t/**\n");
			sb.append("\t* 获取").append(f.getDescription());
			sb.append("\n\t*/\n");
			sb.append("\tpublic void set").append(upName).append('(').append(type).append(' ')
					.append(f.getFieldName()).append(") {\n");
			sb.append("\t\tthis.").append(f.getFieldName()).append(" = ").append(f.getFieldName()).append(";\n\t}\n\n");
			// GET
			sb.append("\t/**\n");
			sb.append("\t* 设置").append(f.getDescription());
			sb.append("\n\t*/\n");
			sb.append("\tpublic ").append(type).append(" get").append(upName).append("() {\n");
			sb.append("\t\treturn ").append(f.getFieldName()).append(";\n\t}\n");
		}
		sb.append("\n}");
		this.code = sb.toString();
	}
	
	public void write() {
		FileWriter fw = null;
		File file = new File(this.path, this.className + ".java");
		try {
			fw = new FileWriter(file);
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write(this.code);
			bw.flush();
			bw.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private String getShortJavaType(FieldBean field) {
		String tp = field.getType();
		if (tp.equals(ConstantCode.DATA_TYPE_FIX_STRING) || tp.equals(ConstantCode.JAVA_TYPE_VAR_STRING)
				|| tp.equals(ConstantCode.JAVA_TYPE_LARGE_STRING)) {
			return "String";
		} else if (tp.equals(ConstantCode.DATA_TYPE_BOOLEAN)) {
			return "boolean";
		} else if (tp.equals(ConstantCode.DATA_TYPE_INT)) {
			return "int";
		} else if (tp.equals(ConstantCode.DATA_TYPE_LONG)) {
			return "long";
		} else if (tp.equals(ConstantCode.DATA_TYPE_DOUBLE)) {
			return "double";
		} else if (tp.equals(ConstantCode.DATA_TYPE_DECIMAL)) {
			return ConstantCode.JAVA_TYPE_BIGDECIMAL;
		} else if (tp.equals(ConstantCode.DATA_TYPE_DATE)) {
			return ConstantCode.JAVA_TYPE_DATE;
		} else if (tp.equals(ConstantCode.DATA_TYPE_INT_LIST) || tp.equals(ConstantCode.DATA_TYPE_STRING_LIST)) {
			return "String";
		}
		return tp;
	}
}
